package comgame.components;

import com.almasb.fxgl.core.math.FXGLMath;
import com.almasb.fxgl.core.math.Vec2;
import com.almasb.fxgl.dsl.FXGL;
import com.almasb.fxgl.entity.component.Component;
import com.almasb.fxgl.time.LocalTimer;
import javafx.geometry.Point2D;
import javafx.util.Duration;

import java.util.Random;

public class MovementComponent extends Component {

    private double speed = 150; // 增大速度值（像素/秒）
    private double rotationSpeed = 5.0;  // 增大转向速度
    private double currentDirection = 0; // 当前角度（弧度制）
    private double targetDirection = FXGLMath.random(0, Math.PI * 2);  // 随机初始目标角度

    // 行为状态
    private enum BehaviorState { FOLLOW_MOUSE, WANDER, CHASE, STOPPED }
    private BehaviorState currentState = BehaviorState.WANDER;

    private Random random = new Random();
    private LocalTimer stateTimer = FXGL.newLocalTimer();
    private Duration stateDuration = Duration.seconds(0);
    private Vec2 wanderDirection = new Vec2();

    private enum SpeedState { NORMAL, SLOWING, DASHING }
    private SpeedState speedState = SpeedState.NORMAL;
    private double targetSpeed = 150;
    private double dashTimer = 0;

    @Override
    public void onAdded() {
        // 初始化状态计时器
        stateTimer.capture();
        // 设置初始随机方向
        wanderDirection.set(FXGLMath.randomPoint2D().normalize());
        // 设置初始状态持续时间
        setRandomStateDuration();

        // 设置初始随机方向
        currentDirection = FXGLMath.random(0, Math.PI * 2);
        entity.setRotation(Math.toDegrees(currentDirection));
    }

    @Override
    public void onUpdate(double tpf) {
        addSpeedVariation(tpf);
        updateState(tpf);
        updateDirection(tpf);
        if (currentState != BehaviorState.STOPPED) {
            moveFish(tpf);
        }
    }

    // 更新行为状态
    private void updateState(double tpf) {
        if (stateTimer.elapsed(stateDuration)) {
            double r = random.nextDouble();
            if (r < 0.10) {
                currentState = BehaviorState.STOPPED; // 10%概率停顿
            } else if (r < 0.20) {
                currentState = BehaviorState.CHASE;   // 10%概率追逐
            } else if (r < 0.80) {
                currentState = BehaviorState.WANDER;  // 60%概率游荡
            } else {
                currentState = BehaviorState.FOLLOW_MOUSE; // 20%概率跟随鼠标
            }
            setRandomStateDuration();
            stateTimer.capture();
        }
    }

    // 设置随机的状态持续时间（1-3秒）
    private void setRandomStateDuration() {
        stateDuration = Duration.seconds(1 + random.nextDouble() * 2);
    }

    // 更新游泳方向
    private void updateDirection(double tpf) {
        switch (currentState) {
            case FOLLOW_MOUSE:
                followMouseBehavior();
                break;
            case WANDER:
                wanderBehavior(tpf);
                flockingBehavior(); // 混合群体行为
                break;
            case CHASE:
                chaseNearestFish();
                break;
            case STOPPED:
                // 停止时不更新方向
                return;
        }

        // 计算最小角度差（修复转向逻辑）
        double angleDiff = targetDirection - currentDirection;
        angleDiff = ((angleDiff + Math.PI) % (2 * Math.PI) + (2 * Math.PI)) % (2 * Math.PI) - Math.PI;
        double maxRotation = rotationSpeed * tpf;
        if (Math.abs(angleDiff) < maxRotation) {
            currentDirection = targetDirection;
        } else {
            currentDirection += Math.signum(angleDiff) * maxRotation;
        }
        currentDirection = normalizeAngle(currentDirection);
    }

    // 群体行为：靠近同伴、对齐方向
    private void flockingBehavior() {
        // 只跟随同色鱼
        String myType = getFishType(entity);
        var neighbors = FXGL.getGameWorld().getEntitiesByType(comgame.entities.EntityType.Fish)
                .stream()
                .filter(e -> e != entity && e.distanceBBox(entity) < 120 && getFishType(e).equals(myType))
                .toList();
        if (neighbors.isEmpty()) return;
        double avgX = 0, avgY = 0, avgDirX = 0, avgDirY = 0;
        int validNeighbors = 0;
        for (var neighbor : neighbors) {
            // 检查邻居是否有MovementComponent
            if (!neighbor.hasComponent(MovementComponent.class)) {
                continue;
            }
            avgX += neighbor.getX();
            avgY += neighbor.getY();
            MovementComponent mc = neighbor.getComponent(MovementComponent.class);
            double dir = mc.currentDirection;
            avgDirX += Math.cos(dir);
            avgDirY += Math.sin(dir);
            validNeighbors++;
        }
        if (validNeighbors == 0) return;
        avgX /= validNeighbors; avgY /= validNeighbors; avgDirX /= validNeighbors; avgDirY /= validNeighbors;
        double toCenterAngle = Math.atan2(avgY - entity.getY(), avgX - entity.getX());
        double alignAngle = Math.atan2(avgDirY, avgDirX);
        // 更倾向于靠近同伴
        targetDirection = 0.8 * toCenterAngle + 0.2 * alignAngle;
    }

    // 追逐最近的鱼
    private void chaseNearestFish() {
        var fishes = FXGL.getGameWorld().getEntitiesByType(comgame.entities.EntityType.Fish);
        com.almasb.fxgl.entity.Entity nearest = null;
        double minDist = Double.MAX_VALUE;
        for (var fish : fishes) {
            if (fish == entity) continue;
            // 只追逐有MovementComponent的鱼
            if (!fish.hasComponent(MovementComponent.class)) continue;
            double dist = fish.distanceBBox(entity);
            if (dist < minDist) {
                minDist = dist;
                nearest = fish;
            }
        }
        if (nearest != null) {
            var myPos = entity.getPosition();
            var targetPos = nearest.getPosition();
            targetDirection = Math.atan2(targetPos.getY() - myPos.getY(), targetPos.getX() - myPos.getX());
        } else {
            // 没有其他鱼时，切回游荡
            wanderBehavior(0.016);
        }
    }

    // 随机游动行为
    private void wanderBehavior(double tpf) {
        if (random.nextDouble() < 0.6 * tpf) {
            double wanderAngle = (random.nextDouble() - 0.5) * Math.PI / 1.5;
            double jitter = (random.nextDouble() - 0.5) * Math.PI / 12;
            wanderDirection.set(
                    (float)Math.cos(currentDirection + wanderAngle + jitter),
                    (float)Math.sin(currentDirection + wanderAngle + jitter)
            ).normalize();
        }
        targetDirection = Math.atan2(wanderDirection.y, wanderDirection.x);
    }

    // 移动鱼（含边界检测）
    private void moveFish(double tpf) {
        double dx = Math.cos(currentDirection) * speed * tpf;
        double dy = Math.sin(currentDirection) * speed * tpf;
        double newX = entity.getX() + dx;
        double newY = entity.getY() + dy;
        double screenWidth = FXGL.getAppWidth();
        double screenHeight = FXGL.getAppHeight();
        double fishWidth = entity.getBoundingBoxComponent().getWidth();
        double fishHeight = entity.getBoundingBoxComponent().getHeight();
        boolean bounced = false;
        if (newX < 0) {
            newX = 0;
            currentDirection = Math.PI - currentDirection;
            bounced = true;
        } else if (newX + fishWidth > screenWidth) {
            newX = screenWidth - fishWidth;
            currentDirection = Math.PI - currentDirection;
            bounced = true;
        }
        if (newY < 0) {
            newY = 0;
            currentDirection = -currentDirection;
            bounced = true;
        } else if (newY + fishHeight > screenHeight) {
            newY = screenHeight - fishHeight;
            currentDirection = -currentDirection;
            bounced = true;
        }
        if (bounced) {
            currentDirection = normalizeAngle(currentDirection);
            targetDirection = currentDirection;
        }
        entity.setPosition(newX, newY);
        entity.setRotation(Math.toDegrees(currentDirection));
    }

    // 速度波动与冲刺前减速
    public void addSpeedVariation(double tpf) {
        switch (speedState) {
            case NORMAL:
                targetSpeed = 150 * (0.8 + 0.4 * random.nextDouble());
                // 偶尔进入减速准备冲刺
                if (random.nextDouble() < 0.01) {
                    speedState = SpeedState.SLOWING;
                    dashTimer = 0.5 + random.nextDouble() * 0.5; // 0.5~1秒减速
                    targetSpeed = 60; // 先慢下来
                }
                break;
            case SLOWING:
                dashTimer -= tpf;
                targetSpeed = 60;
                if (dashTimer <= 0) {
                    speedState = SpeedState.DASHING;
                    dashTimer = 0.3 + random.nextDouble() * 0.3; // 0.3~0.6秒冲刺
                    targetSpeed = 250 + random.nextDouble() * 100; // 冲刺速度
                }
                break;
            case DASHING:
                dashTimer -= tpf;
                targetSpeed = 250 + random.nextDouble() * 100;
                if (dashTimer <= 0) {
                    speedState = SpeedState.NORMAL;
                    targetSpeed = 150 * (0.8 + 0.4 * random.nextDouble());
                }
                break;
        }
        // 让speed平滑靠近targetSpeed
        double lerp = 0.15;
        speed += (targetSpeed - speed) * lerp;
    }

    // 跟随鼠标行为
    private void followMouseBehavior() {
        try {
            // 获取鼠标在游戏世界中的坐标
            Point2D mousePos = FXGL.getInput().getMousePositionWorld();
            if (mousePos == null) return;

            // 获取鱼当前的位置
            Point2D fishPos = entity.getPosition();

            // 计算指向鼠标的向量
            Vec2 toMouse = new Vec2(
                    (float)(mousePos.getX() - fishPos.getX()),
                    (float)(mousePos.getY() - fishPos.getY())
            ).normalize(); // 确保是单位向量

            // 计算目标方向角度（弧度）
            targetDirection = Math.atan2(toMouse.y, toMouse.x);
        } catch (Exception e) {
            // 防止鼠标位置获取失败时崩溃
            System.err.println("获取鼠标位置失败: " + e.getMessage());
        }
    }

    // 角度标准化到 [0, 2π)
    private double normalizeAngle(double angle) {
        angle = angle % (2 * Math.PI);
        if (angle < 0) {
            angle += 2 * Math.PI;
        }
        return angle;
    }

    // 辅助方法：根据图片路径或spawnName区分鱼的类型
    private String getFishType(com.almasb.fxgl.entity.Entity e) {
        try {
            // 你可以用spawnName、图片路径、属性等区分
            // 这里假设用view的图片路径区分
            var viewComponent = e.getViewComponent();
            if (viewComponent == null || viewComponent.getChildren().isEmpty()) {
                return "OtherFish";
            }
            var view = viewComponent.getChildren().get(0);
            if (view instanceof javafx.scene.image.ImageView imgView) {
                var image = imgView.getImage();
                if (image != null) {
                    String url = image.getUrl();
                    if (url != null && url.contains("fish_green")) return "GreenFish";
                    if (url != null && url.contains("fish_red")) return "RedFish";
                }
            }
        } catch (Exception ex) {
            // 防止访问图片时出错
            System.err.println("获取鱼类型时出错: " + ex.getMessage());
        }
        return "OtherFish";
    }
}